import MySQLdb
import string
import pickle
import marshal
import types
import time

TYPES = {'OBJECT':0,
'GROUP':1,
'USER':2,
'FILE':3,
'FOLDER':4,
'LINK':5,
'EVENT':6,
'ACCESS':7,
'NAMESPACE':8}

FREQ = {'MINUTE':60,
'HOUR': 3600,
'DAY': 86400,
'WEEK': 604800,
'MONTH': 262800,
'YEAR': 31536000}


class main():
	
	def get_all_by_type(self, db, type):
		if type == TYPES['LINK']:
			a = []
			db.execute('select * from obj where type='+str(type))
			b = db.fetchall()
	
			for x in b:
				
				o = obj(db, TYPES['LINK'], '')
				o.load_persistent(db, x[0])
				o.load_vals(db, x[0])
				o.load_events(db, x[0])
				o.load_methods(db, x[0])
				a.append(o)

			return a

	def get_all_events(self, db):
		a = []
		db.execute('select * from methodix where time>-1')
		b = db.fetchall()
		#print b
		d = {}
		for x in b:
			db.execute('select objid from obj2method where methodid='+str(x[0]))
			c = db.fetchall()
			for y in c:
				if not d.has_key(y[0]):
					d[y[0]] = []
				a.append(x[2])
				a.append(x[3])
				a.append(x[4])
				d[y[0]].append(a)
				a = []

		return d

class obj():

	type = -1
	name = 'default'
	events = {}	
	keyval = {}
	id = -1
	methods = {}

	def __init__(self):
		return True

	def __init__(self, db, type, name):
		self.keyval = {}
		self.keyval['type'] = type
		self.keyval['name'] = name

	#def __init__(self, db, id):
	#	self.load_persistent(db, id)

	def get_type(self):
		return self.keyval['type']

	def create_persistent(self, db):
		sql = 'insert into obj(type, name) values ("'+str(self.keyval['type'])+'", "'+self.keyval['name']+'")'
		db.execute(sql)
		sql = 'select count(id) from obj'
		db.execute(sql)
		self.keyval['id'] = db.fetchone()[0]

	def load_persistent(self, db, id):
		sql = 'select * from obj where type='+str(self.keyval['type'])+' and id='+str(id)
		db.execute(sql)
		a = db.fetchone()
		if a:
			self.keyval['type'] = a[1]
			self.keyval['name'] = a[2]
			self.keyval['id'] = a[0]

	def add_val(self, p, v):
		self.keyval[p]=v

	def add_event(self, event, t, freq):
		cs = marshal.dumps(event.func_code)
		cs.replace('\\', '\\\\')
		if t>time.time() and t!=-1:
			if self.events.has_key(t):
				self.events[t].append([cs, freq])
			else:
				self.events[t] = []
				self.events[t].append([cs, freq])

	def remove_event(self, t):
		if self.events.has_key(t):
			n = {}
			for x in self.events.keys():
				if t==x: continue
				n[x] = self.events[x]
			self.events.clear()
			self.events = n
			return True


	def add_method(self, method, n):
		cs = marshal.dumps(method.func_code)
		cs.replace('\\', '\\\\')
		self.methods[n]= cs

	def get_val(self, p):
		return self.keyval[p]

	def store_val(self, m, db, val):
		sql = 'select propid from obj2prop where objid='+str(self.keyval['id'])
		print sql
		db.execute(sql)
		a = db.fetchall()
		if a:
			for x in a:
				print x
				sql = 'select property from propix where id='+str(x[0])
				print sql
				db.execute(sql)
				
				c = db.fetchall()

				if c:
					for y in c:
						if val==y[0]:
							sql = 'update propix set value="'+pickle.dumps(self.keyval[val])+'" where id='+str(x[0])+' and property="'+val

+'"' 
							db.execute(sql)
							print sql
							self.commit(m)
							return
				
		sql = 'insert into propix(property, value) values("'+val+'", "'+pickle.dumps(self.keyval[val])+'")'
		db.execute(sql)
		print sql
		self.commit(m)
		sql = 'select count(id) from propix'
		db.execute(sql)
		print sql
		a = db.fetchone()
		sql = 'insert into obj2prop(objid, propid) values('+str(self.keyval['id'])+', '+str(a[0])+')'
		db.execute(sql)
		self.commit(m)
		print sql

	def store_vals(self, m, db):
		for x in self.keyval.keys():
			self.store_val(m, db, x)
		

	def load_vals(self, db, objid):
		sql = 'select * from obj2prop where objid='+str(objid)
		db.execute(sql)
		print sql
		a = db.fetchall()
		if a:
			b = []
			for x in a:
				sql = 'select * from propix where id='+str(x[1])
				db.execute(sql)
				print sql
				b=db.fetchall()
				if b:
					for y in b:
						print y
						c = pickle.loads(y[2])
						self.keyval[y[1]] = c

	def load_methods(self, db, objid):
		sql = 'select * from obj2method where objid='+str(objid)
		db.execute(sql)
		a = db.fetchall()
		if a:
			b = []
			for x in a:
				sql = 'select name, code from methodix where id='+str(x[1])+' and time=-1'
				print sql
				db.execute(sql)
				b = db.fetchall()
				if b:
					print b

					for y in b:
						print y
						c = marshal.loads(y[1])
						self.methods[y[0]] = c


	def load_events(self, db, objid):
		sql = 'select * from obj2method where objid='+str(objid)
		db.execute(sql)
		a = db.fetchall()
		if a:
			b = []
			for x in a:
				sql = 'select * from methodix where id='+str(x[1])
				print sql
				db.execute(sql)
				b=db.fetchall()
				if b:
					print b
					
						
					c = marshal.loads(b[0][2])
					self.events[b[0][3]] = [c, b[0][4]]

	def store_events(self, m, db):
		for x in self.events.keys():
			for y in self.events[x]:
			#print y
			#print self.events[x]
				self.store_event(m, db, x, y[1])


	def store_methods(self, m, db, n):
		sql = 'select methodid from obj2method where objid='+str(self.keyval['id'])
		print sql
		db.execute(sql)
		a = db.fetchall()
		if a:
			for x in a:
				print x
				sql = 'select name from methodix where id='+str(x[0])
				print sql
				db.execute(sql)
				
				c = db.fetchall()

				if c:
					for y in c:
						if n==y[0]:
							#for z in self.events[event]:
							sql = 'update methodix set code="'+marshal.dumps(self.methods[n])+'" where id='+str(x[0])+' and time=-1' 
							db.execute(sql)
							print sql
							self.commit(m)
							return
				
		sql = 'insert into methodix(name, code, time) values("'+n+'", "'+self.methods[n]+'", -1)'
		print sql, sql, sql
		db.execute(sql)
		print sql
		self.commit(m)
		sql = 'select count(id) from methodix'
		db.execute(sql)
		print sql
		a = db.fetchone()
		sql = 'insert into obj2method(objid, methodid) values('+str(self.keyval['id'])+', '+str(a[0])+')'
		db.execute(sql)
		self.commit(m)
		print sql

	def store_event(self, m, db, event, freq):
		sql = 'select methodid from obj2method where objid='+str(self.keyval['id'])
		print sql
		db.execute(sql)
		a = db.fetchall()
		if a:
			for x in a:
				print x
				sql = 'select time from methodix where id='+str(x[0])
				print sql
				db.execute(sql)
				
				c = db.fetchall()
				#print c
				if c:
					for y in c:
						print event, y[0]
						if event>=y[0]:
							#for z in self.events[event]:
							sql = 'update methodix set time='+str(y[0])+' where id='+str(x[0])
							db.execute(sql)
							print sql
							self.commit(m)
							return
				
		sql = 'insert into methodix(name, code, time, freqtype) values("'+'", "'+marshal.dumps(self.events[event][0])+'", '+str(event)+', '+str(freq)+')'
		db.execute(sql)
		print sql
		self.commit(m)
		sql = 'select count(id) from methodix'
		db.execute(sql)
		print sql
		a = db.fetchone()
		sql = 'insert into obj2method(objid, methodid) values('+str(self.keyval['id'])+', '+str(a[0])+')'
		db.execute(sql)
		self.commit(m)
		print sql		

	def execute(self, db, m):
		for x in self.events.keys():
			if x!=-1 and x<time.time():
				for y in self.events[x]:
					code = marshal.loads(y[0]) 
					func = types.FunctionType(code, globals(), "some_func_name") 
					self.add_event(db, time.time()+y[1])
					self.store_events(m, db)
					self.commit(m)
	 				return func(self.import_namespace(db))

	def exec_method(self, db, method, c):
		y = self.methods[method]
		code = marshal.loads(y)
		func = types.FunctionType(code, globals(), "some_func_name")
		return func(self, c)

	def import_namespace(self, db):
		return [1,1]

	def commit(self, db):
		db.commit()


m = MySQLdb.connect('localhost', 'root', '', 'objix')
n = m.cursor()
#o = obj(n, TYPES[0], 'testobj')
#o.create_persistent(n)
#o.add_val('test2', 2)
#o.store_vals(m,n)
#def func(a): print a[0]*8*a[1]
#o.add_event(func, time.time()+10)
#o.store_events(m,n)
#m.commit()
